Recent advances in microprocessor design and component integration have enabled a wide range of devices to offer increasingly complex functionality and “soft” features. Soft features include software applications that enhance and customize the operation of a device. These devices include standard computing devices, such as desktop and laptop computers, portable computing devices, such as personal data assistants, and consumer devices, such as cellular telephones, messaging pagers, gaming consoles, and set top boxes. Most devices now include an operating system to support the soft features and other extensions.
The increased capabilities offered by these software-upgradeable devices have also created certain user expectations. Often, users are not technically savvy and are intolerant of performance compromises occasioned by architectural challenges, such as slow or inconsistent application performance. Similarly, users generally expect to be able to access a host of separate applications, which are implemented at the system level through multitasking. For users, widely available software applications assure a positive experience through consistency and increased exposure across multiple platforms. However, for software developers, engineering software applications for disparate computing platforms entails increased development costs and on-going support and upgrade commitments for each supported architecture.
Managed code platforms provide one solution to software developers seeking to support multiple platforms by presenting a machine-independent and architecture-neutral operating environment. Managed code platforms include programming language compilers and interpreters executed by an operating system as user applications, but which provide virtual runtime environments within which compatible applications can operate. For instance, applications written in the Java programming language, when combined with a Java virtual machine (JVM) runtime environment, can operate on heterogeneous computer systems independent of machine-specific environment and configuration settings. An overview of the Java programming language is described in P. van der Linden, “Just Java,” Ch. 1, Sun Microsystems, Inc. (2d ed. 1997), the disclosure of which is incorporated by reference. JVMs are a critical component to the overall Java operating environment, which can be ported to the full range of computational devices, including memory-constrained consumer devices.
Managed code platforms are generally designed for the monotonic execution of a single application instance. Multiple instances of a managed code platform are executed to simulate multitasking behavior. Such forced concurrency, however, creates several performance problems. First, each instance incurs a startup transient. Executable and startup data must be read from slow persistent storage, which results in slow initial application performance. Similarly, memory is not shared between instances and each additional instance increases the overall memory footprint of the platform by separately loading and instantiating classes, generally problematic in memory-constrained systems. Moreover, data dependencies and deferred initialization of system state can result in non-deterministic execution patterns. Finally, each instance independently determines the relative importance of executing methods and compiles machine code on an ad hoc basis, often causing inconsistent application performance.
Deferred class loading is sometimes necessitated by the dynamic nature of the object oriented languages involved. Dynamic class loading can also adversely affect performance and cause nondeterministic execution behavior. To help improve runtime performance, managed code platforms lazily defer class loading until a class is actually referenced. Deferred class loading conserves the time required to load a class by delaying class loading and compilation until, and if, the class is actually needed. Deferred class loading sacrifices runtime performance for improved application startup. However, for near real time applications, deferred class loading causes non-deterministic execution behavior that increases worst case performance by the longest class loading execution thread. Similarly, deferred class loading exacerbates the resource usage of multiple application instances that each requires the same classes by duplicatively performing identical operations and needlessly consuming memory that could be conserved, if the memory state were shared.
Static preloading of classes and interfaces is currently supported in many Java virtual machines, which allows a build-time tool to pre-process and preload classes and to link the classes into the JVM static executable image before JVM startup. However, static preloading can result in large executable sizes and can be problematic for resource constrained devices, where boot startup time is critical and a combination of slower processor and persistent storage and modest memory can cause significant boot times.
Therefore, there is a need for an approach to providing class preloading in a managed code platform, such as the Java operating environment, to provide concurrently executable applications that share warmed up memory state and to minimize worst case performance.